package com.swu.pad.analysis.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.swu.pad.activity.dao.ActivityDao;
import com.swu.pad.activity.entity.Activity;
import com.swu.pad.analysis.service.AnalysisService;
import com.swu.pad.assignment.dao.AssignmentDao;
import com.swu.pad.assignment.dao.AssignmentPadDao;
import com.swu.pad.assignment.entity.Assignment;
import com.swu.pad.assignment.entity.AssignmentPad;
import com.swu.pad.assignment.service.AssignmentService;
import com.swu.pad.comment.dao.CommentDao;
import com.swu.pad.comment.dao.CommentQuestionDao;
import com.swu.pad.comment.entity.Comment;
import com.swu.pad.comment.entity.CommentQuestion;
import com.swu.pad.course.dao.CourseGroupUserDao;
import com.swu.pad.course.entity.CourseGroupUser;
import com.swu.pad.course.entity.Group;
import com.swu.pad.course.service.CourseService;
import com.swu.pad.system.entity.User;
import com.swu.pad.system.service.UserService;
import com.swu.pad.util.EPLiteClient.EPLiteClient;

@Service
@Transactional
public class AnalysisServiceImpl implements AnalysisService {

	@Autowired
	private ActivityDao activityDao;
	@Autowired
	private UserService userService;
	@Autowired
	private AssignmentDao assignmentDao;
	@Autowired
	private AssignmentPadDao assignmentPadDao;
	@Autowired
	private CourseGroupUserDao courseGroupUserDao;
	@Autowired
	private CommentDao commentDao;
	@Autowired
	private CommentQuestionDao commentQuestionDao;
	@Autowired
	private AssignmentService assignmentService;
	@Autowired
	private CourseService courseService;
	@Autowired
	private EPLiteClient epliteClient;
	// 权重树
	public static TreeMap<Integer, Float> weightTree = new TreeMap<Integer, Float>();
	static {
		// [0,30]->1.0 (30,45]->0.8 (45,60]->0.6 (60,75]->0.4 (75,90]->0.2 (90,)->0.0
		weightTree.put(-1, (float) 1.0);
		weightTree.put(30, (float) 0.8);
		weightTree.put(45, (float) 0.6);
		weightTree.put(60, (float) 0.4);
		weightTree.put(75, (float) 0.2);
		weightTree.put(90, (float) 0.0);
	}

	public Map<String, Object> getGroupRadar(String activityId, User user) {
		// 组内雷达图 {assignment:'',group:'',radar:[{user:'',radar:[{question:'',score:''}]}]}
		Activity activity = activityDao.findOne(activityId);
		Assignment assignment = assignmentDao.findOne(activity.getAssignmentId());
		List<CourseGroupUser> courseGroupUserList = courseService.getUserAssignmentGroup(user.getId(), activity.getAssignmentId(), assignment.getAssignmentType());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignmentId", assignment.getId());
		map.put("assignmentName", assignment.getAssignmentName());
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		if (courseGroupUserList != null && courseGroupUserList.size() > 0) {
			map.put("groupName", courseGroupUserList.get(0).getGroupName());
			String groupId = courseGroupUserList.get(0).getGroupId();
			AssignmentPad assignmentPad = assignmentService.getUserAssignmentPad(assignment.getId(), groupId);
			for (int i = 0; i < courseGroupUserList.size(); i++) {
				Map<String, Object> tempMap = new HashMap<String, Object>();
				tempMap.put("user", courseGroupUserList.get(i).getUserName());
				List<CommentQuestion> commentQuestionList = commentQuestionDao.findByTemplateId(activity.getCommentTemplateId());
				List<Map<String, Object>> tempList = new ArrayList<Map<String, Object>>();
				for (int j = 0; j < commentQuestionList.size(); j++) {
					List<Comment> commentList = commentDao.findByAssignmentPadIdAndAuthorIdAndQuestionId(assignmentPad.getId(), courseGroupUserList.get(i).getUserId(),
							commentQuestionList.get(j).getId());
					if (commentList != null && commentList.size() > 0) {
						Map<String, Object> tempMap0 = new HashMap<String, Object>();
						tempMap0.put("question", commentQuestionList.get(j).getQuestion());
						int score = 0;
						for (int k = 0; k < commentList.size(); k++) {
							score += Integer.parseInt(commentList.get(k).getScore());
						}
						tempMap0.put("score", (score + 0.0) / commentList.size());
						tempList.add(tempMap0);
					}
				}
				tempMap.put("radar", tempList);
				list.add(tempMap);
			}
		}
		map.put("radar", list);
		return map;
	}

	public Map<String, Object> getCourseRadar(String activityId, User user) {
		// 组内雷达图 {assignment:'',group:'',radar:[{user:'',radar:[{question:'',score:''}]}]}
		Activity activity = activityDao.findOne(activityId);
		Assignment assignment = assignmentDao.findOne(activity.getAssignmentId());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignmentId", assignment.getId());
		map.put("assignmentName", assignment.getAssignmentName());
		List<CommentQuestion> commentQuestionList = commentQuestionDao.findByTemplateId(activity.getCommentTemplateId());
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		List<AssignmentPad> assignmentPadList = assignmentPadDao.findAssignmentPadByAssignmentId(assignment.getId());
		for (int j = 0; j < commentQuestionList.size(); j++) {
			int score = 0, count = 0;
			Map<String, Object> tempMap = new HashMap<String, Object>();
			for (int i = 0; i < assignmentPadList.size(); i++) {
				List<Comment> commentList = commentDao.findByAssignmentPadIdAndQuestionId(assignmentPadList.get(i).getId(), commentQuestionList.get(j).getId());
				if (commentList != null && commentList.size() > 0) {
					for (int k = 0; k < commentList.size(); k++) {
						score += Integer.parseInt(commentList.get(k).getScore());
					}
					count += commentList.size();
				}
			}
			tempMap.put("question", commentQuestionList.get(j).getQuestion());
			tempMap.put("score", count == 0 ? 0.0 : (score + 0.0) / count);
			list.add(tempMap);
		}
		map.put("radar", list);
		return map;
	}

	public Map<String, Object> getGroupWordPie(String activityId, User user) {
		// 组内饼图 {assignment:'',group:'',pie:[{user:'',word:''}]}
		Activity activity = activityDao.findOne(activityId);
		Assignment assignment = assignmentDao.findOne(activity.getAssignmentId());
		List<CourseGroupUser> courseGroupUserList = courseService.getUserAssignmentGroup(user.getId(), activity.getAssignmentId(), assignment.getAssignmentType());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignmentId", assignment.getId());
		map.put("assignmentName", assignment.getAssignmentName());
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		if (courseGroupUserList != null && courseGroupUserList.size() > 0) {
			map.put("groupName", courseGroupUserList.get(0).getGroupName());
			String groupId = courseGroupUserList.get(0).getGroupId();
			AssignmentPad assignmentPad = assignmentService.getUserAssignmentPad(assignment.getId(), groupId);
			List authorList = epliteClient.listAuthorsOfPad(assignmentPad.getId());
			for (int i = 0; i < authorList.size(); i++) {
				Map<String, Object> tempMap = new HashMap<String, Object>();
				tempMap.put("user", epliteClient.getAuthorName(authorList.get(i).toString()));
				List authorRevisions = epliteClient.getAuthorRevisions(assignmentPad.getId(), authorList.get(i).toString());
				int wordCount = 0;
				for (int j = 0; j < authorRevisions.size(); j++) {
					int textCount = (Integer) ((Map) authorRevisions.get(j)).get("textCount") - 1;
					wordCount += textCount;
				}
				tempMap.put("wordCount", wordCount);
				list.add(tempMap);
			}
		}
		map.put("pie", list);
		return map;
	}

	public Map<String, Object> getCourseWordPie(String activityId, User user) {
		// 组内饼图 {assignment:'',group:'',pie:[{user:'',word:''}]}
		Activity activity = activityDao.findOne(activityId);
		Assignment assignment = assignmentDao.findOne(activity.getAssignmentId());
		List<CourseGroupUser> courseGroupUserList = courseGroupUserDao.findCourseGroupUserByCourseIdAndGroupType(assignment.getCourseId(), assignment.getAssignmentType());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignmentId", assignment.getId());
		map.put("assignmentName", assignment.getAssignmentName());
		int wordCount = 0;
		if (courseGroupUserList != null && courseGroupUserList.size() > 0) {
			String groupId = courseGroupUserList.get(0).getGroupId();
			List<AssignmentPad> assignmentPadList = assignmentPadDao.findAssignmentPadByAssignmentId(assignment.getId());
			for (int j = 0; j < assignmentPadList.size(); j++) {
				for (int i = 0; i < courseGroupUserList.size(); i++) {
					List allRevisions = epliteClient.getAllRevisions(assignmentPadList.get(j).getId());
					for (int k = 0; k < allRevisions.size(); k++) {
						int textCount = (Integer) ((Map) allRevisions.get(k)).get("textCount") - 1;
						wordCount += textCount;
					}
				}
			}
		}
		map.put("wordCount", (wordCount + 0.0) / courseGroupUserList.size());
		return map;
	}

	public Map<String, Object> getGroupVersionBar(String activityId, User user) {
		// 组内饼图 {assignment:'',group:'',pie:[{user:'',word:''}]}
		Activity activity = activityDao.findOne(activityId);
		Assignment assignment = assignmentDao.findOne(activity.getAssignmentId());
		List<CourseGroupUser> courseGroupUserList = courseService.getUserAssignmentGroup(user.getId(), activity.getAssignmentId(), assignment.getAssignmentType());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignmentId", assignment.getId());
		map.put("assignmentName", assignment.getAssignmentName());
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		if (courseGroupUserList != null && courseGroupUserList.size() > 0) {
			map.put("groupName", courseGroupUserList.get(0).getGroupName());
			String groupId = courseGroupUserList.get(0).getGroupId();
			AssignmentPad assignmentPad = assignmentService.getUserAssignmentPad(assignment.getId(), groupId);
			List authorList = epliteClient.listAuthorsOfPad(assignmentPad.getId());
			for (int i = 0; i < authorList.size(); i++) {
				Map<String, Object> tempMap = new HashMap<String, Object>();
				tempMap.put("user", epliteClient.getAuthorName(authorList.get(i).toString()));
				List authorRevisions = epliteClient.getAuthorRevisions(assignmentPad.getId(), authorList.get(i).toString());
				tempMap.put("versionCount", authorRevisions.size());
				list.add(tempMap);
			}
		}
		map.put("bar", list);
		return map;
	}

	public Map<String, Object> getCourseVersionBar(String activityId, User user) {
		// 组内饼图 {assignment:'',group:'',pie:[{user:'',word:''}]}
		Activity activity = activityDao.findOne(activityId);
		Assignment assignment = assignmentDao.findOne(activity.getAssignmentId());
		List<CourseGroupUser> courseGroupUserList = courseGroupUserDao.findCourseGroupUserByCourseIdAndGroupType(assignment.getCourseId(), assignment.getAssignmentType());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignmentId", assignment.getId());
		map.put("assignmentName", assignment.getAssignmentName());
		int versionCount = 0;
		if (courseGroupUserList != null && courseGroupUserList.size() > 0) {
			String groupId = courseGroupUserList.get(0).getGroupId();
			List<AssignmentPad> assignmentPadList = assignmentPadDao.findAssignmentPadByAssignmentId(assignment.getId());
			for (int j = 0; j < assignmentPadList.size(); j++) {
				List allRevisions = epliteClient.getAllRevisions(assignmentPadList.get(j).getId());
				versionCount += allRevisions.size();
			}
		}
		map.put("versionCount", (versionCount + 0.0) / courseGroupUserList.size());
		return map;
	}

	public Map<String, Object> getFocusLine(String activityId, User user) {
		Activity activity = activityDao.findOne(activityId);
		Assignment assignment = assignmentDao.findOne(activity.getAssignmentId());
		List<CourseGroupUser> courseGroupUserList = courseService.getUserAssignmentGroup(user.getId(), activity.getAssignmentId(), assignment.getAssignmentType());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignmentId", assignment.getId());
		map.put("assignmentName", assignment.getAssignmentName());
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		if (courseGroupUserList != null && courseGroupUserList.size() > 0) {
			map.put("groupName", courseGroupUserList.get(0).getGroupName());
			String groupId = courseGroupUserList.get(0).getGroupId();
			AssignmentPad assignmentPad = assignmentService.getUserAssignmentPad(assignment.getId(), groupId);
			List authorList = epliteClient.listAuthorsOfPad(assignmentPad.getId());
			for (int i = 0; i < authorList.size(); i++) {
				Map<String, Object> tempMap = new HashMap<String, Object>();
				tempMap.put("user", epliteClient.getAuthorName(authorList.get(i).toString()));
				List authorRevisions = epliteClient.getAuthorRevisions(assignmentPad.getId(), authorList.get(i).toString());
				tempMap.put("versionCount", authorRevisions.size());
				list.add(tempMap);
			}
		}
		map.put("bar", list);
		return null;
	}

	public List getPadFocus(String activityId, String userId) {
		Activity activity = activityDao.findOne(activityId);
		CourseGroupUser courseGroupUser = assignmentService.getUserAssignmentSession(activity.getAssignmentId(), userId);
		AssignmentPad assignmentPad = assignmentService.getUserAssignmentPad(activity.getAssignmentId(), courseGroupUser.getGroupId());
		List authorList = (List) epliteClient.listAuthorsOfPad(assignmentPad.getId());
		List<Object> tempList = new ArrayList<Object>();
		for (Object authorId : authorList) {
			Map<String, Object> tempMap = new HashMap<String, Object>();
			tempMap.put("user", epliteClient.getAuthorName(authorId.toString()));
			tempMap.put("focus", getUserfocus(assignmentPad.getId(), authorId.toString()));
			tempList.add(tempMap);
		}
		return tempList;
	}

	/**
	 * 获取用户某个pad的专注度
	 * @param authorId 
	 * @param padId 
	 * @return [{focusValue=9, time=1458098216953},{}]
	 */
	public List getUserfocus(String padId, String authorId) {
		List list = epliteClient.getAuthorRevisions(padId, authorId);

		if (list != null && list.size() >= 2) {
			List<Object> tempList = new ArrayList<Object>();
			for (int i = 0; i < list.size() - 1; i++) {
				long versionTime1 = (Long) ((Map) list.get(i)).get("timestamp");
				long versionTime2 = (Long) ((Map) list.get(i + 1)).get("timestamp");
				int differTime = (int) (Math.abs(versionTime2 - versionTime1) / 1000);

				Map<String, Object> tempMap = new HashMap<String, Object>();
				tempMap.put("focus", getWeight(differTime));
				tempMap.put("time", ((Map) list.get(i + 1)).get("timestamp"));
				tempList.add(tempMap);
			}
			return tempList;
		}
		return null;
	}

	/**
	 * 获取权重值
	 * @param differTime
	 * @param weightTree
	 * @return
	 */
	public static float getWeight(int differTime) {
		return weightTree.headMap(differTime, false).lastEntry().getValue();
	}
}
